package com.sahyadri.web.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

import com.sahyadri.web.bean.Category;
import com.sahyadri.web.bean.CategoryEntry;
import com.sahyadri.web.bean.GalleryDetails;
import com.sahyadri.web.bean.Location;
import com.sahyadri.web.bean.MenuEntry;
import com.sahyadri.web.bean.Review;
import com.sahyadri.web.util.DateTimeUtil;
import com.sahyadri.web.util.service.adpater.OrganizationServiceAdapter;
 
@Controller
@RequestMapping("/")
public class DashboardController {
	private static final Logger LOG = Logger
			.getLogger(DashboardController.class);
	
	@Autowired
	public OrganizationServiceAdapter organizationServiceAdapter;
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateTimeUtil.DEFAULT_DATE_FORMAT);
		TimeZone timeZone = TimeZone.getTimeZone("IST");
		dateFormat.setTimeZone(timeZone);
		dateFormat.setLenient(true);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
        binder.registerCustomEditor(Boolean.class, null, new CustomBooleanEditor( "true", "false", true));
	}
	
	
	
	/**
	 * This will be called for each request for this controller. 
	 * it check user cookies for selected location previously.
	 * If user is new or delete his cookies, system will update with default location.
	 * 
	 * 
	 * @param session
	 * @param model
	 */
	
	
	@ModelAttribute
	public void setupCookies(HttpSession session, HttpServletRequest request, ModelMap model) {
		LOG.debug("setupCookies()");
		if(request.getParameter("selectedLocationId")!= null) {
			session.setAttribute("selectedLocationId",request.getParameter("selectedLocationId"));
		}
		 
		String selectedLocationId = (String)session.getAttribute("selectedLocationId");
		
		 List<Location> locations = organizationServiceAdapter.getAllLocations();
		 if(locations != null && locations.size() != 0 ) {
			 model.addAttribute("locations", locations);
			 if(selectedLocationId == null) {
				 selectedLocationId = new Long(locations.get(0).getId()).toString();
				 model.addAttribute("location", locations.get(0));
				 session.setAttribute("selectedLocationId",""+selectedLocationId);
				 
			 }else{
				 Location location = findLocation(locations, new Long(selectedLocationId).longValue()); //locations details.
				 if(location == null){
					 selectedLocationId = new Long(locations.get(0).getId()).toString();
					 model.addAttribute("location", locations.get(0));
					 session.setAttribute("selectedLocationId",""+selectedLocationId);
				 }
				 model.addAttribute("location", location);
			 }
		 }
			 
		 model.addAttribute("selectedLocationId", selectedLocationId);
	}
	
	private Location findLocation(List<Location> locations, Long locationId) {
		for(Location location:locations) {
			if(locationId == location.getId()) {
				return location;
			}
		}
		return null;
	}
	
	
	
	@RequestMapping(value = "/public/mask/user/location", method = RequestMethod.POST)
	public String maskLocation(@RequestParam("id") long locationId,  
			HttpSession session, ModelMap model) {
		LOG.debug("Masking User location id to " + locationId);
		session.setAttribute("selectedLocationId",""+locationId);
		
		return "dashboardPageView";
	}
	@RequestMapping(value="/public/home", method = RequestMethod.GET)
	public String homePage(ModelMap model) {
		
		LOG.debug("in welcome ()");
		
		return "dashboardPageView";
 
	}
	
	@RequestMapping(value="/public/aboutus", method = RequestMethod.GET)
	public String aboutUsPage(ModelMap model) {
		
		LOG.debug("in aboutUsPage()");
		
		return "aboutUsPageView";
 
	}
	
	@RequestMapping(value="/public/menus", method = RequestMethod.GET)
	public String MenuPage(ModelMap model) {
		
		LOG.debug("in MenuPage()");
		
		return "menuPageView";
 
	}
	
	@RequestMapping(value="/public/category/list", method = RequestMethod.GET)
	public String setupCategoryList(HttpSession session, ModelMap model) {
		
		LOG.debug("in setupCategoryList()");
		long locationId = getLocationIdFromSession(session);
		List<CategoryEntry> categoryList = organizationServiceAdapter.getPublicCategoryList(locationId);
		model.addAttribute("categoryList", categoryList);
		return "jsonView";
 
	}
	
	@RequestMapping(value="/public/category/item", method = RequestMethod.GET)
	public String getCategoryItemList(@RequestParam("categoryId") long categoryId, HttpSession session, ModelMap model) {
		
		LOG.debug("in getCategoryItemList()");
		List<MenuEntry> menuList = organizationServiceAdapter.getCategoryMenuList(categoryId);
		model.addAttribute("menuList", menuList);
		return "jsonView";
 
	}
	@RequestMapping(value="/public/photogallery", method = RequestMethod.GET)
	public String photoGalleryPage(HttpSession session, ModelMap model) {
		
		LOG.debug("in photoGalleryPage()");
		long locationId = getLocationIdFromSession(session);
		List<GalleryDetails> galleryList = organizationServiceAdapter.getGalleryList(locationId);
		model.addAttribute("galleryList", galleryList);
		return "photoGalleryPageView";
 
	}
	
	@RequestMapping(value="/public/offer", method = RequestMethod.GET)
	public String offerPage(ModelMap model) {
		
		LOG.debug("in offerPage()");
		
		return "offerPageView";
 
	}
	
	private long getLocationIdFromSession(HttpSession session ){
		String selectedLocationId = (String) session.getAttribute("selectedLocationId");
		if(StringUtils.hasText(selectedLocationId)) {
			return new Long(selectedLocationId).longValue();
		}
		return 0;
	}
	
	@RequestMapping(value="/public/reviews", method = RequestMethod.GET)
	public String reviewsPage(HttpSession session, ModelMap model) {
		
		LOG.debug("in reviewsPage()");
		loadReviewList(session, model);
		return "reviewsPageView";
 
	}
	/**
	 * Added dummy method for partial page render
	 * @param session
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/public/reviews/page", method = RequestMethod.GET)
	public String reviewsPagePartialRender(HttpSession session, ModelMap model) {
		
		LOG.debug("in reviewsPage()");
		loadReviewList(session, model);
		return "reviewPageLoadView";
 
	}
	
	private void loadReviewList(HttpSession session, ModelMap model){
		long locationId = getLocationIdFromSession(session);
		List<Review> reviewList = organizationServiceAdapter.getPublishedReviews(locationId);
		model.addAttribute("reviewList", reviewList);
	}
	
	@RequestMapping(value = "/public/reviews/add")
	public String setupNewReviewPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewMenuPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("review", new Review());
		return "reviewAddView";
	}
	
	
	
	@RequestMapping(value = "/public/reviews/save")
	public String saveReviewDetails(Review review, HttpSession session, ModelMap model) {
		LOG.debug("in saveReviewDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveReview(locationId, review);
		List<Review> reviewList = organizationServiceAdapter.getReviewList(locationId);
		model.addAttribute("reviewList",reviewList);
		return "reviewConfirmationView";
	}
	
	
	@RequestMapping(value="/public/contactus", method = RequestMethod.GET)
	public String contactUsPage(ModelMap model) {
		
		LOG.debug("in contactUsPage()");
		
		return "contactUsPageView";
 
	}
 
	
 
}